﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpGL.SceneGraph.Assets;
using SharpGL;
using System.IO;

namespace bitzhuwei.FeedingFrenzy.WorldModel
{
    public class GameFish : GameObject
    {
        public override string ToString()
        {
            return string.Format("{0},p:{1},v:{2}", this.Species, this.Position, this.Speed);
            //return base.ToString();
        }
        public static void LoadTextures(string directory, OpenGL gl)
        {
            foreach (var item in Directory.GetFiles(directory))
            {
                try
                {
                    Texture t = new Texture();
                    t.Create(gl, item);
                    t.Name = item;
                    //t.Bind(gl);
                    speciesDict.Add(item, t);
                }
                catch (Exception)
                {
                }
            }
        }
        public static void Dispose(OpenGL gl)
        {
            foreach (var item in speciesDict.Values)
            {
                item.Destroy(gl);
            }
        }

        public static GameFish GetInstance(string species)
        {
            GameFish result = null;
            if (speciesDict.ContainsKey(species))
            {
                result = new GameFish(species);
            }
            return result;  
        }

        private static Dictionary<string, Texture> speciesDict = new Dictionary<string, Texture>();

        public List<string> GetSpecies()
        {
            var result = speciesDict.Keys.ToList();
            return result;  
        }

        private TriTuple<float> speed = new TriTuple<float>(0, 0, 0);

        public TriTuple<float> Speed
        {
            get { return speed; }
            set { speed = value; }
        }
        private TriTuple<double> position = new TriTuple<double>(0, 0, 0);
        private string _species = string.Empty;

        public string Species
        {
            get { return _species; }
            set { _species = value; }
        }

        public TriTuple<double> Position
        {
            get { return position; }
            set { position = value; }
        }

        public override void Draw(SharpGL.OpenGL gl)
        {
            if (speciesDict.ContainsKey(this._species))
            {
                //  Load the identity matrix.
                gl.LoadIdentity();

                //gl.PushMatrix();
                gl.Translate(position.X, position.Y, position.Z);
                //gl.Rotate(speed.X, speed.Y, speed.Z);
                //gl.BindTexture(OpenGL.GL_TEXTURE_2D, speciesDict[this._species].TextureName);
                speciesDict[this._species].Bind(gl);
                gl.Color(r, g, b, life);

                gl.Begin(OpenGL.GL_TRIANGLE_STRIP);				// Build Quad From A Triangle Strip
                gl.TexCoord(1, 1); gl.Vertex(position.X + 0.5f, position.Y + 0.5f, Position.Z); // Top Right
                gl.TexCoord(0, 1); gl.Vertex(position.X - 0.5f, position.Y + 0.5f, Position.Z); // Top Left
                gl.TexCoord(1, 0); gl.Vertex(position.X + 0.5f, position.Y - 0.5f, Position.Z); // Bottom Right
                gl.TexCoord(0, 0); gl.Vertex(position.X - 0.5f, position.Y - 0.5f, Position.Z); // Bottom Left
                gl.End();						// Done Building Triangle Strip
                gl.Flush();
                //gl.PopMatrix();
            }
            //base.Draw(gl);
        }

        protected GameFish(string species)
        {
            // TODO: Complete member initialization
            this._species = species;
        }

        static Random rand = new Random();

        public override void Update()
        {
            //this.life = rand.NextDouble();
            //this.r = rand.NextDouble();
            //this.g = rand.NextDouble();
            //this.b = rand.NextDouble();

            if (rand.Next(0,10) < 1)
            {
                this.Speed.X += (0.0f + rand.Next(0, 20) - 10) / 400;
                this.Speed.Y += (0.0f + rand.Next(0, 20) - 10) / 400;
                this.Speed.Z += (0.0f + rand.Next(0, 20) - 10) / 400;
            }

            this.position.X += this.speed.X;
            this.position.Y += this.speed.Y;
            this.position.Z += this.speed.Z;
            if (this.position.X < this.World.MinScope.X)
            {
                this.position.X = this.World.MinScope.X;
                this.speed.X = -this.speed.X;
            }
            if (this.position.X > this.World.MaxScope.X)
            {
                this.position.X = this.World.MaxScope.X;
                this.speed.X = -this.speed.X;
            }
            if (this.position.Y < this.World.MinScope.Y)
            {
                this.position.Y = this.World.MinScope.Y;
                this.speed.Y = -this.speed.Y;
            }
            if (this.position.Y > this.World.MaxScope.Y)
            {
                this.position.Y = this.World.MaxScope.Y;
                this.speed.Y = -this.speed.Y;
            }
            if (this.position.Z < this.World.MinScope.Z)
            {
                this.position.Z = this.World.MinScope.Z;
                this.speed.Z = -this.speed.Z;   
            }
            if (this.position.Z > this.World.MaxScope.Z)
            {
                this.position.Z = this.World.MaxScope.Z;
                this.speed.Z = -this.speed.Z;
            }
            //base.Update();
        }

        public double life = 1f;					// Particle Life
        public double r = 1f;					// Red Value
        public double g = 1f;					// Green Value
        public double b = 1f;					// Blue Value

        public static List<GameFish> GetRandomFishes(int count)
        {
            List<GameFish> result = new List<GameFish>();
            foreach (var item in speciesDict)
            {
                var fish = new GameFish(item.Key);
                result.Add(fish);
            }
            while (result.Count < count)
            {
                foreach (var item in speciesDict)
                {
                    if (rand.Next(0, 100) < 50)
                    {
                        var fish = new GameFish(item.Key);
                        result.Add(fish);
                        if (result.Count >= count)
                            break;
                    }
                }
            }
            return result;
        }

    }
}
